package org.andao.security.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.andao.core.base.service.BaseServiceImpl;
import org.andao.core.cache.EhCacheManager;
import org.andao.core.dao.helper.Page;
import org.andao.core.dao.jdbc.JdbcSupportDao;
import org.andao.core.exception.ServiceException;
import org.andao.core.utils.ExCollectionUtils;
import org.andao.core.utils.ExStringUtils;
import org.andao.security.cache.CacheSecManager;
import org.andao.security.model.Resource;
import org.andao.security.model.Role;
import org.andao.security.service.RoleService;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;



/**
 * 系统安全权限-角色管理服务.
 * 
 * @author Marco.hu(hzg139@163.com)
 */
@Service("roleService")
@Transactional
public class RoleServiceImpl extends BaseServiceImpl<Role> implements RoleService{
	
	@Autowired 
	@Qualifier("defaultJdbcSupportDao")	
	private JdbcSupportDao jdbcDao;//注入jdbc template 支持

	/*
	 *  根据所选资源ID更新保存角色	
	 */
	public void saveOrUpdateRole(Role role, List<String> ids)  throws ServiceException{
		if(ExStringUtils.isBlank(role.getResourceid())){
			//校验重复性
			Role r = findUniqueByProperty("roleCode", role.getRoleCode());
			if(null != r){
				throw new ServiceException("已存在相同编号的角色，请重新输入！");
			}
		}
		if(null != ids && ids.size()>0){
			List list = exGeneralHibernateDao.findEntitysByIds(Resource.class, ids);//查找资源列表			
						
			List<Resource> delList = new ArrayList<Resource>();
			
			for(Resource oldRes : role.getAuthoritys()){//剔除删除的
				if(!ids.contains(oldRes.getResourceid())){
					delList.add(oldRes);
				}
			}
			role.getAuthoritys().removeAll(delList);
			if(ExCollectionUtils.isNotEmpty(list)){
				role.getAuthoritys().addAll(list);
			}
			
		}
		saveOrUpdate(role);				
		reloadResourceRoleRef(role);//重新加载角色授权资源		
	
	}	

	/*
	 * 根据角色编码获取角色对象
	 */
	@Transactional(readOnly=true)
	public Role getRoleByRolecode(String rolecode) throws ServiceException {	
		return (Role) exGeneralHibernateDao.findUniqueByProperty(Role.class,"roleCode",rolecode);
	}

	//根据条件查找
	@Transactional(readOnly=true)
	public Page findRoleByCondition(Map<String, Object> condition, Page page) throws ServiceException {
		List<Criterion> objCriterion = new ArrayList<Criterion>();
		if(condition.containsKey("roleCode")){//根据资源编码
			objCriterion.add(Restrictions.eq("roleCode",condition.get("roleCode")));
		}
		if(condition.containsKey("roleName")){//资源名称
			objCriterion.add(Restrictions.like("roleName","%"+condition.get("roleName")+"%"));
		}
		objCriterion.add(Restrictions.eq("isDeleted", 0));//是否删除 =0
		
		return exGeneralHibernateDao.findByCriteria(Role.class,page,objCriterion.toArray(new Criterion[objCriterion.size()]));
	}

	/*
	 * 批量删除
	 * (non-Javadoc)
	 * @see com.hnjk.security.service.IRoleService#deleteArray(java.lang.String[])
	 */
	public void deleteArray(String[] ids) throws ServiceException{
		if(ids.length>0){
			for(int index=0;index<ids.length;index++){
				deleteRole(ids[index]);
			}
		}
	}

	/*
	 * 单个删除
	 */
	public void deleteRole(String roleid) throws ServiceException {
		Role role = get(roleid);
		Role parentRole = role.getParent();
		if(null != parentRole){
			parentRole.getChildren().remove(role);
			update(parentRole);
		}else{
			delete(role);
		}
		EhCacheManager.getCache(CacheSecManager.CACHE_SEC_ROLES).remove(roleid);		
	}
	
	
	/*
	 *重新加载角色授权资源
	 *
	 */
	private void reloadResourceRoleRef(Role role){
				
		Map<String, Set<String>> resRoleMap = (Map<String, Set<String>>)EhCacheManager.getCache(CacheSecManager.CACHE_SEC_ROLE_RESOURCE)
													.get(CacheSecManager.CACHE_SEC_ROLE_RESOURCE);		
				
		String value = role.getRoleCode();		
		for(Resource resource : role.getAuthoritys()) {//更新缓存该角色缓存 key - url : value - rolecode
			String key = resource.getResourcePath();			
			if(key == null || key.equalsIgnoreCase("")) continue;
			
			Set<String> roleSet = resRoleMap.get(key);//获取该资源的角色列表
			if(null == roleSet){
				roleSet = new HashSet<String>();
				roleSet.add(value);
				resRoleMap.put(key, roleSet);
				continue;
			}
			if(!roleSet.contains(value)){
				roleSet.add(value);
			}
					
		}
		EhCacheManager.getCache(CacheSecManager.CACHE_SEC_ROLE_RESOURCE).put(CacheSecManager.CACHE_SEC_ROLE_RESOURCE, resRoleMap);//更新
		EhCacheManager.getCache(CacheSecManager.CACHE_SEC_ROLES).put(role.getResourceid(),role);	// 将角色放入缓存
			
		logger.info("加载系统角色："+role.getRoleName()+",资源-角色映射："+resRoleMap.size()+"条...");
		
	}

	//查找角色树
	@Override
	@Transactional(readOnly=true)
	public List<Role> findRoleTreeList(String parentCode) throws ServiceException {
		StringBuilder sb = new StringBuilder();
		/*
		 * ORACLE ONLY
		sb.append("select * from "+HibernateBeanHelper.getEntiryOfTable(Role.class)+" t where t.isdeleted=0  start with ");
		if(ExStringUtils.isNotEmpty(parentCode)){
			sb.append( " t.roleCode = '"+parentCode+"' ");
		}else{
			sb.append( " t.parentid is null ");
		}
		 
		sb.append( " connect by prior t.resourceid=t.parentid order siblings by t.showOrder");
		try {
			return jdbcDao.getBaseJdbcTemplate().findList(sb.toString(), Role.class, null);
		} catch (Exception e) {
			throw new ServiceException(e);
		}
		*/		
		Map<String,Object> param = new HashMap<String,Object>();
		sb.append(" from "+Role.class.getSimpleName()+" t where t.isDeleted = :isDeleted");
		param.put("isDeleted", 0);
		sb.append(" order by t.showOrder ");
		return this.findByHql(sb.toString(), param);
	}
	
	
	
}
